﻿using System;
using System.Threading;
using System.Windows.Forms;
using ALApps.Graphics.Interface.Engine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SunrayEngine.Managers;
using SunrayEngine.Maps;

namespace SunrayEngine
{
    /// <summary>
    /// The Main Sunray Engine Class.
    /// </summary>
    public class SRMain : Game
    {
        #region fields
        private UpdateManager updateManager; //The update manager.
        private DrawManager drawManager; //The draw manager.
        private GraphicsDeviceManager graphics; //The graphicsDeviceManager.
        private MapManager mapManager;
        private GUIManager gui;
        #endregion

        #region properties
        /// <summary>
        /// Get all game input.
        /// </summary>
        public InputManager Input { get; protected set; }

        /// <summary>
        /// The Spritebatch, used for drawing everything 2D.
        /// </summary>
        public SpriteBatch SpriteBatch { get; protected set; }

        /// <summary>
        /// Script manager.
        /// </summary>
        public PythonManager Py { get; protected set; }
        #endregion

        #region initialization
        public SRMain()
            : base()
        {
            Console.Title = "Sunray Engine Console";
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
 
            //Initialize SR managers
            updateManager = new UpdateManager(this, 3);
            drawManager = new DrawManager(this, 2);
        }

        /// <summary>
        /// Loads all content that is needed through the content manager.
        /// </summary>
        protected override void LoadContent()
        {
            //Will not be used in final version!
         
            SpriteBatch = new SpriteBatch(GraphicsDevice);

            base.LoadContent();
        }

        /// <summary>
        /// Initializes in game values, called after load.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();
            
            IsMouseVisible = true;

            Map.Device = GraphicsDevice;

            //Component initialization
            mapManager = new MapManager(this, SpriteBatch);

            string cwd = System.IO.Directory.GetCurrentDirectory();
            int cwdi = cwd.IndexOf(@"\Svn");
            string svnPath = cwd.Substring(0, cwdi + 4);

            mapManager.LoadMap(svnPath + @"\SunRayEngine.MapEditor\SunRayEngine.MapEditor\SunRayEngine.MapEditor\bin\x86\Debug\test0.srm", "test");
            mapManager.SetActiveMap("test");
  
            //Component adding
            Components.Add(mapManager);

            //We initialize the python manager togheter with a Link script that set up everything python related.
            string pypath = svnPath + @"\SunRayEngine\SunRayEngineTest\SunRayEngineTest\SunRayEngineTest\Python\";
            Py = new PythonManager(this, pypath + "Link.py", pypath + "Load.py");

            RunPythonInitialization();

            try
            {
                string baseGuiPath = svnPath +  @"\SunRayEngine\SunRayEngineTest\SunRayEngineTest\SunRayEngineTest\GUI\";
                gui = new GUIManager(this, SpriteBatch,
                    baseGuiPath + @"Python\",
                    baseGuiPath + @"Design\",
                    baseGuiPath + "pyPaths.txt",
                    baseGuiPath + "designPaths.txt",
                    "default");

                CopyPyVarsToGui("pylink");
                Input = InterfaceEngine.Input;
            }
            catch (Exception e)
            { 
                MessageBox.Show(e.ToString());
            }

            //Create a test subject for the character manager and character class.
            Py.Execute(@"
from sunray.characters import Player, CharacterPart

b = tex['dude'].Bounds

part = CharacterPart()
part.texture = tex['dude']
part.name = 'body'
part.width = b.Width / 3
part.height = b.Height / 3
part.rotation = 5.0
temp = part.getbounds()
part.origin = Vector2(temp.X + temp.Width / 2, temp.Y + temp.Height / 2)

testchar = Player(game)
testchar.position = Vector2(100, 100)
testchar.width = b.Width / 3
testchar.height = b.Height / 3
testchar.speed = 0.1
testchar['body'] = part

pylink['CharacterManager'].AddCharacter(testchar)
");
        }
        #endregion

        #region methods
        protected override void EndRun()
        {
            base.EndRun();

            drawManager.DisposeThreads();
            updateManager.DisposeThreads();
        }

        /// <summary>
        /// Handels all the updateabel game logic.
        /// </summary>
        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        /// <summary>
        /// Handels the drawing of everything.
        /// </summary>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            SpriteBatch.Begin();

            base.Draw(gameTime);

            SpriteBatch.End();
        }

        protected void CopyPyVarsToGui(params string[] keys)
        {
            foreach (string key in keys)
            {
                try
                {
                    InterfaceEngine.Scripting[key] = Py[key];
                }
                catch
                {
                    Console.WriteLine(string.Format("There was an error when copying the key: {0} to the gui.", key));
                }
            }
        }

        protected virtual void RunPythonInitialization()
        {
            Py.Execute(@"
import clr
clr.AddReference('Microsoft.Xna.Framework')
clr.AddReference('Microsoft.Xna.Framework.Graphics')

from Microsoft.Xna.Framework import *
from Microsoft.Xna.Framework.Graphics import *
");
        }
        #endregion
    }
}
